package nz.ac.massey.cs.reg;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

/**
 * applies linear regression algorithm to x,y coordinates
 * using linear algebra method:
 * <p/>
 * <pre>beta = inv(transpose(x)*x)*(transpose(x)*y)</pre>
 *
 * @author Hussain Al-Mutawa
 * @version 1.0
 */
public class LinearRegression implements Regressor {
    public final double beta0, beta1;

    public LinearRegression(Map<? extends Number, ? extends Number> XY) {
        double a = 0, b = 0, c = 0, d = 0, e = 0, f = 0;
        for (Entry<? extends Number, ? extends Number> entry : XY.entrySet()) {
            double x = entry.getKey().doubleValue();
            double y = entry.getValue().doubleValue();
            a += 1;
            b += x;
            c += x;
            d += x * x;
            e += y;
            f += x * y;
        }
        double det = (a * d) - (b * c);
        beta0 = (d * e - c * f) / det;
        beta1 = (a * f - b * e) / det;
    }

    public List<Double> beta() {
        return Collections.unmodifiableList(Arrays.asList(beta0, beta1));
    }

    public double predict(double x) {
        return beta0 + beta1 * x;
    }

    @Override
    public double inverse(double y) {
        return (y - beta0) / beta1;
    }
}